<?php

declare(strict_types=1);

namespace DreamCat\ControllerParamGen\HelperClass\Factory;

use Laminas\Diactoros\StreamFactory;
use Psr\Http\Message\ServerRequestInterface;
use Laminas\Diactoros\ServerRequestFactory as LamServerRequestFactory;

/**
 * 测试用的Http请求创建工厂
 * @author vijay
 */
class ServerRequestFactory
{
    /**
     * 创建一个将json数据post过来的请求对象
     * @param string $uri uri地址
     * @param mixed $json 要传输的数据，如果不是string会调用json_encode
     * @param array $get get参数
     * @param string $domain 域名
     * @return ServerRequestInterface
     */
    public static function createByPostJson(
        string $uri,
        mixed $json,
        array $get = [],
        string $domain = "test.domain.com"
    ): ServerRequestInterface {
        if (!is_string($json)) {
            $json = json_encode($json);
        }
        $server = [
            "SCRIPT_URL" => $uri,
            "SCRIPT_URI" => "http://{$domain}{$uri}",
            "CONTENT_TYPE" => "application/json; charset=utf-8",
            "HTTP_ACCEPT" => "*/*",
            "HTTP_CACHE_CONTROL" => "no-cache",
            "HTTP_HOST" => $domain,
            "HTTP_ACCEPT_ENCODING" => "gzip, deflate",
            "CONTENT_LENGTH" => strlen($json),
            "HTTP_CONNECTION" => "keep-alive",
            "PATH" => "",
            "SERVER_NAME" => $domain,
            "SERVER_ADDR" => "127.0.0.1",
            "SERVER_PORT" => "80",
            "REMOTE_ADDR" => "127.0.0.1",
            "DOCUMENT_ROOT" => __FILE__,
            "REQUEST_SCHEME" => "http",
            "CONTEXT_PREFIX" => "",
            "CONTEXT_DOCUMENT_ROOT" => __DIR__,
            "SCRIPT_FILENAME" => __FILE__,
            "REMOTE_PORT" => "59242",
            "GATEWAY_INTERFACE" => "CGI/1.1",
            "SERVER_PROTOCOL" => "HTTP/1.1",
            "REQUEST_METHOD" => "POST",
            "QUERY_STRING" => "",
            "REQUEST_URI" => $uri,
            "SCRIPT_NAME" => "/web.php",
            "PHP_SELF" => "/web.php",
            "REQUEST_TIME_FLOAT" => microtime(true),
            "REQUEST_TIME" => time(),
        ];
        $streamFactory = new StreamFactory();
        /** @noinspection PhpIncompatibleReturnTypeInspection */
        return LamServerRequestFactory::fromGlobals($server, $get)
            ->withMethod("POST")
            ->withBody($streamFactory->createStream($json));
    }

    /**
     * 创建一个将form数据post过来的请求对象
     * @param string $uri uri地址
     * @param array $form 要传输的数据数组
     * @param array $get get参数
     * @param string $domain 域名
     * @param bool $withParsed 是否加入 ParsedBody
     * @return ServerRequestInterface
     */
    public static function createByPostForm(
        string $uri,
        array $form,
        array $get = [],
        string $domain = "test.domain.com",
        bool $withParsed = true
    ): ServerRequestInterface {
        $formStr = http_build_query($form);
        $server = [
            "SCRIPT_URL" => $uri,
            "SCRIPT_URI" => "http://{$domain}{$uri}",
            "CONTENT_TYPE" => "application/x-www-form-urlencoded; charset=utf-8",
            "HTTP_ACCEPT" => "*/*",
            "HTTP_CACHE_CONTROL" => "no-cache",
            "HTTP_HOST" => $domain,
            "HTTP_ACCEPT_ENCODING" => "gzip, deflate",
            "CONTENT_LENGTH" => strlen($formStr),
            "HTTP_CONNECTION" => "keep-alive",
            "PATH" => "",
            "SERVER_NAME" => $domain,
            "SERVER_ADDR" => "127.0.0.1",
            "SERVER_PORT" => "80",
            "REMOTE_ADDR" => "127.0.0.1",
            "DOCUMENT_ROOT" => __FILE__,
            "REQUEST_SCHEME" => "http",
            "CONTEXT_PREFIX" => "",
            "CONTEXT_DOCUMENT_ROOT" => __DIR__,
            "SCRIPT_FILENAME" => __FILE__,
            "REMOTE_PORT" => "59242",
            "GATEWAY_INTERFACE" => "CGI/1.1",
            "SERVER_PROTOCOL" => "HTTP/1.1",
            "REQUEST_METHOD" => "POST",
            "QUERY_STRING" => "",
            "REQUEST_URI" => $uri,
            "SCRIPT_NAME" => "/web.php",
            "PHP_SELF" => "/web.php",
            "REQUEST_TIME_FLOAT" => microtime(true),
            "REQUEST_TIME" => time(),
        ];
        /** @noinspection PhpIncompatibleReturnTypeInspection */
        /** @var ServerRequestInterface $request */
        $request = LamServerRequestFactory::fromGlobals($server, $get, $form)
            ->withMethod("POST")
            ->withBody((new StreamFactory())->createStream($formStr));
        if (!$withParsed) {
            $request = $request->withParsedBody(null);
        }
        return $request;
    }
}

# end of file
